package com.nts.visionworks.core.utility;

/**
 * 연관있는 두 개의 객체를 함께 보관하기 위한 인터페이스를 제공한다.
 * @see 보관하는 두 개의 객체를 좌/우로 구분하는 것은 편의 상의 목적으로 구분하는 것이므로 별 다른 의미는 없다.
 * @author Devcken
 * @param <L> 보관하려는 객체 중 좌측 객체의 타입을 나타낸다.
 * @param <R> 보관하려는 객체 중 우측 객체의 타입을 나타낸다.
 */
public class Pair<L, R>
{
	/**
	 * 두 개의 객체 중 좌측 객체의 인스턴스를 나타낸다.
	 */
	private L left;
	
	/**
	 * 두 개의 객체 중 우측 객체의 인스턴스를 나타낸다.
	 */
	private R right;
	
	public Pair(L left, R right)
	{
		this.left = left;
		this.right = right;
	}
	
	@Override
	public int hashCode()
	{
		int leftHash = this.left == null ? 0 : this.left.hashCode();
		int rightHash = this.right == null ? 0 : this.right.hashCode();
		
		return leftHash + rightHash;
	}

	@Override
	@SuppressWarnings("unchecked")
	public boolean equals(Object obj)
	{
		if (!(obj instanceof Pair<?, ?>)) return false;
		
		Pair<L, R> target = (Pair<L, R>)obj;
		
		return ((this.left == null && target.getLeft() == null) || this.getLeft().equals(target.getLeft())) &&
				(this.right == null && target.getRight() == null) || this.getRight().equals(target.getRight());
	}

	public L getLeft()
	{
		return left;
	}

	public void setLeft(L left)
	{
		this.left = left;
	}

	public R getRight()
	{
		return right;
	}

	public void setRight(R right)
	{
		this.right = right;
	}
}